/**
 * User: denis
 * Date: Mar 27, 2009
 */
package ua.com.stormlabs.jsitemapper;


import org.apache.log4j.Logger;
import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LinkExtractor {

    private static final Logger log = Logger.getLogger(LinkExtractor.class);

    private static LinkExtractor ourInstance = new LinkExtractor();

    private final List<String> extractPatterns = new LinkedList<String>();
    private final List<String> filterPatterns = new LinkedList<String>();
    private String host;

    public static LinkExtractor getInstance() {
        return ourInstance;
    }

    private LinkExtractor() {
    }

    public List<String> getLinks(String html, String location) {
        if (!location.endsWith("/")) {
            location = location + "/";
        }
        LinkedList<String> links = new LinkedList<String>();
        for (String regexp : extractPatterns) {
            Pattern pattern = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(html);
            while (matcher.find()) {
                String link = matcher.group(1);
                link = applyFilters(link);
                if (StringUtils.isBlank(link)) continue;
                link = normalizeRelativeLink(link, location);
//                log.debug("Extracted link " + link);
                links.add(link);
            }
        }
        return links;
    }

    public void addExtractorPattern(String regexp) {
        extractPatterns.add(regexp);
    }

    public void setHost(String host) {
        this.host = host.replaceAll("/$", "");
    }

    private String applyFilters(String link) {
        String origLink = link;
        if (isForeignLink(link)) return "";
        for (String filter : filterPatterns) {
            link = link.replaceAll(filter, "");
        }
        if (StringUtils.isBlank(link)) {
            log.debug("Filters dropped link '" + origLink + "'");
            LinkPool.getInstance().addSkipped(origLink);
        }
        return link;
    }

    private boolean isForeignLink(String link) {
        if (link.startsWith("http://") && !link.startsWith(host)) {
            log.debug("Foreign link '" + link + "'");
            return true;
        }
        return false;
    }

    private String normalizeRelativeLink(String link, String location) {
        if (link.startsWith("/")) {
            link = host + link;
        } else if (!link.startsWith("http://")) {
            link = location + link;
        }
        return link;
    }

    public void addFilterPattern(String pattern) {
        filterPatterns.add(pattern);
    }
}
